<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2017/6/6
 * Time: 16:22
 */
namespace app\v1\model;

use app\v1\logic\MyFunctions;
use think\Db;

class Paypublic extends MyFunctions
{

    public function pay($url, $obj)
    {
        $obj['nonce_str'] = $this->create_noncestr();
        $stringA = $this->formatQueryParaMap($obj, false);
        $stringSignTemp = $stringA . "&key=" . config("PARTNERKEY");
        $sign = strtoupper(md5($stringSignTemp));
        $obj['sign'] = $sign;
        $postXml = $this->arrayToXml($obj);
        $responseXml = $this->curl_post_ssl($url, $postXml);
        return $responseXml;
    }

    public function create_noncestr($length = 32)
    {
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }

    public function formatQueryParaMap($paraMap, $urlencode)
    {
        $buff = "";
        ksort($paraMap);
        foreach ($paraMap as $k => $v) {
            if (null != $v && "null" != $v && "sign" != $k) {
                if ($urlencode) {
                    $v = urlencode($v);
                }
                $buff .= $k . "=" . $v . "&";
            }
        }
        $reqPar = "";
        if (strlen($buff) > 0) {
            $reqPar = substr($buff, 0, strlen($buff) - 1);
        }
        return $reqPar;
    }

//数组转XML
    public function arrayToXml($arr)
    {
        $xml = "<xml>";
        foreach ($arr as $key => $val) {
            if (is_numeric($val)) {
                $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
            } else {
                $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
            }
        }
        $xml .= "</xml>";
        return $xml;
    }

    public function curl_post_ssl($url, $vars, $second = 30)
    {

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

        curl_setopt($ch, CURLOPT_SSLCERT, ROOT_PATH . 'public/static/cert/apiclient_cert.pem');
        curl_setopt($ch, CURLOPT_SSLKEY, ROOT_PATH . 'public/static/cert/apiclient_key.pem');
        curl_setopt($ch, CURLOPT_CAINFO, ROOT_PATH . 'public/static/cert/rootca.pem');

        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $vars);
        $data = curl_exec($ch);
        if ($data) {
            curl_close($ch);
            return $data;
        } else {
            $error = curl_errno($ch);
            echo "call faild, errorCode:$error\n";
            curl_close($ch);
            return $error;
        }
    }

    /*
    * 支付选中订单
    * @param $ids|id组
    * */
    public function payWeiXinTX($ids)
    {

        $payWxArr = Db::query("select * from spread_pay  where id in ($ids) and state =1");
        $url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers';//支付链接
        $returnStr = "";
        $obj1 = array();
        foreach ($payWxArr as $key) {
            $money = (int)($key['pay_money'] * 100);
            $obj1['openid'] = $key['openid'];
            $obj1['amount'] = $money;
            $obj1['desc'] = config("title") . "id:" . $key['spread_user_id'] . "提现.";
            $obj1['mch_appid'] = config("appid");//appid
            $obj1['mchid'] = config("mchid");//商户编号
            $obj1['partner_trade_no'] = $key['spread_user_id'] . date('Ymd') . $key['id'];
            $obj1['spbill_create_ip'] = $_SERVER['REMOTE_ADDR'];
            $obj1['check_name'] = "NO_CHECK";
            $result = $this->pay($url, $obj1);//判定返回值
            if ($this->cut($result, "<result_code>", "</result_code>") == '<![CDATA[FAIL]]>') {
                $returnStr = $returnStr . $key['spread_user_id'] . "提现失败,";
                $state = 0;
                $msg = str_replace("<", "", $this->cut($result, "<err_code_des>", "</err_code_des>"));
                $msg = str_replace("<", "", $msg);
                $data = array("state" => 3, 'msg' => $msg, 'pay_day' => time());
                Db::name("spread_pay")->where("id", $key['id'])->update($data);//标记为未支付
            } else {
                $state = 2;
                $returnStr = $returnStr . $key['spread_user_id'] . "提现" . $key['pay_money'] . "提现成功,";
                $payment_no = str_replace(array("<![CDATA[", "]]>"), "", $this->cut($result, "<payment_no>", "</payment_no>"));//获取微信订单号
                $data = array("state" => 2, 'pay_day' => time(), "msg" => "", "wx_result" => $payment_no);
                Db::name("spread_pay")->where("id", $key['id'])->update($data);//标记为已支付
            }
        }
        return array("msg" => $returnStr, "state" => $state);
    }

    /*
     * 退款
     * */
    public function callBackPay(){

    }

    /*
     * 支付列表
     *
     * */
    public function getPayArr($state = 1,$model="weixin")
    {
        if(!$model){
            return Db::field("a.*,b.relaname,b.username,b.bank_peopel_name,b.bank")->table("spread_pay a,spread_user b")->where("a.spread_user_id = b.id")->where(["a.state" => $state])->order("a.id desc")->paginate(10);
        }else{
            return Db::field("a.*,b.relaname,b.username,b.bank_peopel_name,b.bank")->table("spread_pay a,spread_user b")->where("a.spread_user_id = b.id")->where(["a.state" => $state,"a.pay_model"=>$model])->order("a.id desc")->paginate(10);
        }
    }

    /*
* 退回选中订单
* @param  $ids|id组 $state|退回模式 1退回为未支付,2退回给用户并删除订单
* */
    public function returnWeiXinTX($ids, $state)
    {
        if ($state == 1) {
            //退回未支付
            return Db::name("spread_pay")->where("id", "in", $ids)->update(['state' => 1]) ? 1 : 0;
        } else {
            // 启动事务
            Db::startTrans();
            foreach (explode(",", $ids) as $key => $val) {
                try {
                    //退回余额
                    $userPayArr = Db::name("spread_pay")->where("id", $val)->find();//查询此订单
                    $res1 = Db::name("spread_user")->where("id", $userPayArr['spread_user_id'])->setInc('money', $userPayArr['pay_money']);//退回余额给用户
                    $res2 = Db::name("spread_pay")->where("id", $val)->delete();//删除此订单

                    // 提交事务
                    Db::commit();
                } catch (\Exception $e) {
                    // 回滚事务
                    Db::rollback();
                }
                if (!$res1 || !$res2) {
                    return 0;
                }
            }

            return 1;

        }

    }


    /*
  * 删除选中订单
  * @param  $ids|id组
  * */
    public function delWeiXinTX($ids)
    {
        return Db::name("spread_pay")->where("id", "in", $ids)->delete() ? 1 : 0;
    }


    /*
     * 标记为已支付
     * */
    public function payOk($ids){
        return Db::name("spread_pay")->where("id","in",$ids)->update(['pay_day'=>time(),"state"=>2]);
    }

    /*
     * 统计每日支付
     * */
    public function  countPayByDay(){
        return Db::name("spread_pay")->field("FROM_UNIXTIME(pay_day, '%Y-%m-%d')  pay_day,sum(pay_money) count_money,count(id) num")
            ->group("FROM_UNIXTIME(pay_day, '%Y-%m-%d')")
            ->order("FROM_UNIXTIME(pay_day, '%Y-%m-%d') desc")
            ->where("state",2)
            ->paginate(20,true);
    }

    /*
    * 统计每日充值
    * */
    public function  countRechargeByDay(){
        return Db::name("user_recharge")->field("FROM_UNIXTIME(pay_day, '%Y-%m-%d')  pay_day,sum(money) count_money,count(id) num")
            ->group("FROM_UNIXTIME(pay_day, '%Y-%m-%d')")
            ->order("FROM_UNIXTIME(pay_day, '%Y-%m-%d') desc")
            ->paginate(20,true);
    }
}